/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.gallery3d.app;

import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
//import android.support.v4.print.PrintHelper;
import android.view.Menu;
import android.view.MenuItem;
import android.view.Window;
import android.view.WindowManager;

import com.android.gallery3d.R;
import com.android.gallery3d.common.ApiHelper;
import com.android.gallery3d.data.DataManager;
import com.android.gallery3d.data.MediaItem;
import com.android.gallery3d.filtershow.cache.ImageLoader;
import com.android.gallery3d.ui.GLRoot;
import com.android.gallery3d.ui.GLRootView;
import com.android.gallery3d.util.PanoramaViewHelper;
import com.android.gallery3d.util.ThreadPool;
import com.android.photos.data.GalleryBitmapPool;

import java.io.FileNotFoundException;

public class AbstractGalleryActivity extends Activity implements GalleryContext {
	private static final String TAG = "AbstractGalleryActivity";
	private GLRootView mGLRootView;
	private StateManager mStateManager;
	private GalleryActionBar mActionBar;
	private OrientationManager mOrientationManager;
	private TransitionStore mTransitionStore = new TransitionStore();
	private boolean mDisableToggleStatusBar;
	private PanoramaViewHelper mPanoramaViewHelper;

	private AlertDialog mAlertDialog = null;
	private BroadcastReceiver mMountReceiver = new BroadcastReceiver() {
		@Override
		public void onReceive(Context context, Intent intent) {
			if (getExternalCacheDir() != null)
				onStorageReady();
		}
	};
	private IntentFilter mMountFilter = new IntentFilter(
			Intent.ACTION_MEDIA_MOUNTED);

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		mOrientationManager = new OrientationManager(this);
		toggleStatusBarByOrientation();
		getWindow().setBackgroundDrawable(null);
		mPanoramaViewHelper = new PanoramaViewHelper(this);
		mPanoramaViewHelper.onCreate();
		doBindBatchService();
	}

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		mGLRootView.lockRenderThread();
		try {
			super.onSaveInstanceState(outState);
			getStateManager().saveState(outState);
		} finally {
			mGLRootView.unlockRenderThread();
		}
	}

	@Override
	public void onConfigurationChanged(Configuration config) {
		super.onConfigurationChanged(config);
		mStateManager.onConfigurationChange(config);
		getGalleryActionBar().onConfigurationChanged();
		invalidateOptionsMenu();
		toggleStatusBarByOrientation();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		super.onCreateOptionsMenu(menu);
		return getStateManager().createOptionsMenu(menu);
	}

	@Override
	public Context getAndroidContext() {
		return this;
	}

	@Override
	public DataManager getDataManager() {
		return ((GalleryApp) getApplication()).getDataManager();
	}

	@Override
	public ThreadPool getThreadPool() {
		return ((GalleryApp) getApplication()).getThreadPool();
	}

	public synchronized StateManager getStateManager() {
		if (mStateManager == null) {
			mStateManager = new StateManager(this);
		}
		return mStateManager;
	}

	public GLRoot getGLRoot() {
		return mGLRootView;
	}

	public OrientationManager getOrientationManager() {
		return mOrientationManager;
	}

	@Override
	public void setContentView(int resId) {
		super.setContentView(resId);
		mGLRootView = (GLRootView) findViewById(R.id.gl_root_view);
	}

	protected void onStorageReady() {
		if (mAlertDialog != null) {
			mAlertDialog.dismiss();
			mAlertDialog = null;
			unregisterReceiver(mMountReceiver);
		}
	}

	@Override
	protected void onStart() {
		super.onStart();
		if (getExternalCacheDir() == null) {
			OnCancelListener onCancel = new OnCancelListener() {
				@Override
				public void onCancel(DialogInterface dialog) {
					finish();
				}
			};
			OnClickListener onClick = new OnClickListener() {
				@Override
				public void onClick(DialogInterface dialog, int which) {
					dialog.cancel();
				}
			};
			AlertDialog.Builder builder = new AlertDialog.Builder(this)
					.setTitle(R.string.no_external_storage_title)
					.setMessage(R.string.no_external_storage)
					.setNegativeButton(android.R.string.cancel, onClick)
					.setOnCancelListener(onCancel);
			if (ApiHelper.HAS_SET_ICON_ATTRIBUTE) {
				setAlertDialogIconAttribute(builder);
			} else {
				builder.setIcon(android.R.drawable.ic_dialog_alert);
			}
			mAlertDialog = builder.show();
			registerReceiver(mMountReceiver, mMountFilter);
		}
		mPanoramaViewHelper.onStart();
	}

	@TargetApi(ApiHelper.VERSION_CODES.HONEYCOMB)
	private static void setAlertDialogIconAttribute(AlertDialog.Builder builder) {
		builder.setIconAttribute(android.R.attr.alertDialogIcon);
	}

	@Override
	protected void onStop() {
		super.onStop();
		if (mAlertDialog != null) {
			unregisterReceiver(mMountReceiver);
			mAlertDialog.dismiss();
			mAlertDialog = null;
		}
		mPanoramaViewHelper.onStop();
	}

	@Override
	protected void onResume() {
		super.onResume();
		mGLRootView.lockRenderThread();
		try {
			getStateManager().resume();
			getDataManager().resume();
		} finally {
			mGLRootView.unlockRenderThread();
		}
		mGLRootView.onResume();
		mOrientationManager.resume();
	}

	@Override
	protected void onPause() {
		super.onPause();
		mOrientationManager.pause();
		mGLRootView.onPause();
		mGLRootView.lockRenderThread();
		try {
			getStateManager().pause();
			getDataManager().pause();
		} finally {
			mGLRootView.unlockRenderThread();
		}
		GalleryBitmapPool.getInstance().clear();
		MediaItem.getBytesBufferPool().clear();
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		mGLRootView.lockRenderThread();
		try {
			getStateManager().destroy();
		} finally {
			mGLRootView.unlockRenderThread();
		}
		doUnbindBatchService();
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		mGLRootView.lockRenderThread();
		try {
			getStateManager().notifyActivityResult(requestCode, resultCode,
					data);
		} finally {
			mGLRootView.unlockRenderThread();
		}
	}

	@Override
	public void onBackPressed() {
		// send the back event to the top sub-state
		GLRoot root = getGLRoot();
		root.lockRenderThread();
		try {
			getStateManager().onBackPressed();
		} finally {
			root.unlockRenderThread();
		}
	}

	public GalleryActionBar getGalleryActionBar() {
		if (mActionBar == null) {
			mActionBar = new GalleryActionBar(this);
		}
		return mActionBar;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		GLRoot root = getGLRoot();
		root.lockRenderThread();
		try {
			return getStateManager().itemSelected(item);
		} finally {
			root.unlockRenderThread();
		}
	}

	protected void disableToggleStatusBar() {
		mDisableToggleStatusBar = true;
	}

	// Shows status bar in portrait view, hide in landscape view
	private void toggleStatusBarByOrientation() {
		if (mDisableToggleStatusBar)
			return;

		Window win = getWindow();
		if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
			win.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
		} else {
			win.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
		}
	}

	public TransitionStore getTransitionStore() {
		return mTransitionStore;
	}

	public PanoramaViewHelper getPanoramaViewHelper() {
		return mPanoramaViewHelper;
	}

	protected boolean isFullscreen() {
		return (getWindow().getAttributes().flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0;
	}

	private BatchService mBatchService;
	private boolean mBatchServiceIsBound = false;
	private ServiceConnection mBatchServiceConnection = new ServiceConnection() {
		@Override
		public void onServiceConnected(ComponentName className, IBinder service) {
			mBatchService = ((BatchService.LocalBinder) service).getService();
		}

		@Override
		public void onServiceDisconnected(ComponentName className) {
			mBatchService = null;
		}
	};

	private void doBindBatchService() {
		bindService(new Intent(this, BatchService.class),
				mBatchServiceConnection, Context.BIND_AUTO_CREATE);
		mBatchServiceIsBound = true;
	}

	private void doUnbindBatchService() {
		if (mBatchServiceIsBound) {
			// Detach our existing connection.
			unbindService(mBatchServiceConnection);
			mBatchServiceIsBound = false;
		}
	}

	public ThreadPool getBatchServiceThreadPoolIfAvailable() {
		if (mBatchServiceIsBound && mBatchService != null) {
			return mBatchService.getThreadPool();
		} else {
			throw new RuntimeException("Batch service unavailable");
		}
	}

	public void printSelectedImage(Uri uri) {
		if (uri == null) {
			return;
		}
		String path = ImageLoader.getLocalPathFromUri(this, uri);
		if (path != null) {
			Uri localUri = Uri.parse(path);
			path = localUri.getLastPathSegment();
		} else {
			path = uri.getLastPathSegment();
		}
		// PrintHelper printer = new PrintHelper(this);
		// try {
		// printer.printBitmap(path, uri);
		// } catch (FileNotFoundException fnfe) {
		// Log.e(TAG, "Error printing an image", fnfe);
		// }
	}
}
